package com.farm.learn.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.map.HashedMap;

import com.alibaba.fastjson.JSON;
import com.farm.core.time.TimeTool;
import com.farm.learn.domain.ClassChapter;
import com.farm.learn.domain.ClassHour;
import com.farm.learn.domain.Classt;
import com.farm.learn.domain.ex.ClassView;
import com.farm.learn.service.ClasstServiceInter;
import com.farm.parameter.FarmParameterService;
import com.farm.sfile.domain.FileBase;
import com.farm.sfile.service.FileBaseServiceInter;
import com.farm.util.spring.BeanFactory;

/**
 * 保存课程到磁盘
 * 
 * @author macpl
 *
 */
public class ClassSaveToDisker {

	private static String curent_classid;
	/**
	 * 0：完成，1：启动中，2：处理中，
	 */
	private static String state = "3";
	private static String message = "";
	private static ClasstServiceInter classTServiceImpl = (ClasstServiceInter) BeanFactory.getBean("classtServiceImpl");

	private static FileBaseServiceInter fileBaseServiceImpl = (FileBaseServiceInter) BeanFactory
			.getBean("fileBaseServiceImpl");

	/**
	 * 执行导出
	 */
	public static void toSave(final String classid) {
		if (state.equals("0")) {
			state = "1";
			message = "启动中";
			curent_classid = null;
		}
		Classt classt = classTServiceImpl.getClasstEntity(classid);
		if (curent_classid != null && !curent_classid.equals(classid)) {
			throw new RuntimeException("已有课程" + classt.getName() + "正在导出!");
		}
		if (curent_classid != null && curent_classid.equals(classid)) {
			return;
		}
		Thread t = new Thread(new Runnable() {
			public void run() {
				curent_classid = classid;
				state = "2";
				message = "处理中...";
				try {
					appRun();
				} finally {
					state = "0";
					message = "完成";
				}
			}
		});
		t.start();
	}

	@SuppressWarnings("unchecked")
	private static void appRun() {
		ClassView classv = classTServiceImpl.getClassView(curent_classid);
		String dirPath = FarmParameterService.getInstance().getParameter("config.doc.file.export");
		String classTitle = replaceSpecialCharacters(classv.getClasst().getName());
		// 創建基本目錄
		File baseDir = kmDir(new File(dirPath + File.separator + classTitle + TimeTool.getTimeDate14()));
		// 写入课程信息
		Map<String, Object> infos = new HashedMap();
		infos.put("等级", classv.getClasst().getDifficulty());
		infos.put("时长", classv.getClasst().getAltime());
		infos.put("简述", classv.getClasst().getShortintro());
		infos.put("作者", classv.getClasst().getOutauthor());
		infos.put("名称", classv.getClasst().getName());
		infos.put("简述", classv.getIntroText());
		writeObjToTxt(new File(baseDir.getPath() + File.separator + "readme.txt"), infos);
		List<ClassChapter> chapters = classv.getChapters();
		List<ClassHour> hours = classv.getHours();
		int n = 1;
		int cno = 1;
		try {
			for (ClassChapter chapter : chapters) {
				// 創建目錄
				File chapterDir = kmDir(new File(baseDir.getPath() + File.separator
						+ replaceSpecialCharacters("No" + cno + "-" + chapter.getTitle())));
				Map<String, Object> chapterInfo = new HashedMap();
				chapterInfo.put("名称", chapter.getTitle());
				chapterInfo.put("简述", chapter.getNote());
				// 写入信息
				writeObjToTxt(new File(chapterDir.getPath() + File.separator + "readme.txt"), chapterInfo);
				// 章节内的序号
				int no = 1;
				for (ClassHour hour : hours) {
					if (hour.getChapterid().equals(chapter.getId())) {

						String classNo = ("000000" + n).substring(("000000" + n).length() - 3, ("000000" + n).length());

						message = "处理中课程..." + n + "/" + hours.size();

						if (hour.getFilemodel().equals("1")) {
							// 本地文件

							FileBase filebase = fileBaseServiceImpl.getFilebaseEntity(hour.getFileid());
							// 寫入附件
							copyFile(
									new File(
											chapterDir.getPath() + File.separator
													+ replaceSpecialCharacters(classTitle+"-No" + classNo + "-" + hour.getTitle()
															+ "." + filebase.getExname())),
									fileBaseServiceImpl.getFile(filebase));
						}
						if (hour.getFilemodel().equals("2")) {
							// 外部文件
							Map<String, Object> fileInfo = new HashedMap();
							fileInfo.put("download-url::", hour.getFileurl());
							writeObjToTxt(
									new File(
											chapterDir.getPath() + File.separator
													+ replaceSpecialCharacters(
															classTitle+"-No" + classNo + "-" + hour.getTitle() + ".file.txt")),
									fileInfo);
						}
						if (hour.getFilemodel().equals("3")) {
							// iframe内嵌
							Map<String, Object> fileInfo = new HashedMap();
							fileInfo.put("iframe-url:", hour.getFileurl());
							writeObjToTxt(
									new File(
											chapterDir.getPath() + File.separator
													+ replaceSpecialCharacters(
															classTitle+"-No" + classNo + "-" + hour.getTitle() + ".iframe.txt")),
									fileInfo);
						}

						Thread.sleep(100);
						n++;
						no++;
					}
				}
				cno++;
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 替換文件夾名稱的特殊字符
	 * 
	 * @param dirPath
	 * @return
	 */
	public static String replaceSpecialCharacters(String dirPath) {
		/*
		 * windows下文件名中不能含有：\ / : * ? " < > | 英文的这些字符 ，这里使用"."、"'"进行替换。 \/:?| 用.替换 "<>
		 * 用'替换
		 */
		dirPath = dirPath.replaceAll("[/\\\\:*?|]", ".");
		dirPath = dirPath.replaceAll("[\"<>]", "'");
		return dirPath;
	}

	/**
	 * 拷貝一下文件
	 * 
	 * @param classt
	 * @param file
	 */
	private static void copyFile(File file, File playfile) {
		FileInputStream fileInputStream = null;
		FileOutputStream fileOutputStream = null;
		try {
			fileInputStream = new FileInputStream(playfile);
			fileOutputStream = new FileOutputStream(file);
			byte[] buf = new byte[1024];
			int readLength = 0;
			while ((readLength = fileInputStream.read(buf)) != -1) {
				// 边读取边写入
				fileOutputStream.write(buf, 0, readLength);// 一定要使用这个方法，否则可能复制的图片不能打开
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (fileInputStream != null) {
					fileInputStream.close();
				}
				if (fileOutputStream != null) {
					fileOutputStream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 将对象信息写入文本文件
	 * 
	 * @param classt
	 * @param file
	 */
	private static void writeObjToTxt(File file, Map<String, Object> infos) {
		FileWriter fw = null;
		try {
			fw = new FileWriter(file);
			fw.write(JSON.toJSON(infos).toString());// 将字符串写入到指定的路径下的文件中
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 創建一個目錄
	 * 
	 * @param dir
	 * @return
	 */
	private static File kmDir(File dir) {
		if (!dir.exists() || !dir.isDirectory()) {
			dir.mkdirs();
		}
		return dir;
	}

	/**
	 * 获得导出进度状态
	 * 
	 * @return
	 */
	public static String getProgressState() {
		return state;
	}

	/**
	 * 获得导出进度信息
	 * 
	 * @return
	 */
	public static String getProgressMessage() {
		return message;
	}

}
